package com.xiaren.dao;

import com.xiaren.bean.FileBean;
import com.xiaren.common.IConstant;
import com.xiaren.common.ObjectConstant;
import com.xiaren.ui.tree.JTreeBiz;
import com.xiaren.ui.tree.JTreeNode;
import com.xiaren.util.*;
import com.xiaren.util.Base64;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.channels.FileChannel;
import java.util.*;
import java.util.List;


/**
 * Created by xiaren on 2016/12/23.
 * @主页 http://www.leaf123.cn/
 * @邮箱 xia5523@qq.com
 */
public class FileDao extends BaseDao {

    public static String BOLD = "bold";
    public static String FONT_SIZE = "fontSize";
    public static String FORE_GROUND = "foreGround";


    @Override
    public void save(FileBean fileBean) {
        System.out.println("保存文本内容：save============");
        try {
            DaoReadWriteFile.reWriteFile(IConstant.PATH
                            + fileBean.getId(),
                    fileBean.getjTextPane().getText().replaceAll("\r", ""), true);
            deleteImageName(String.valueOf(fileBean.getId()));
            List<DocumentDto> documentDtoList = new ArrayList<>();
            for (int i = 0; i < fileBean.getDocument().getLength(); ) {
                if (fileBean.getStyledDocument().getCharacterElement(i).getName().equals("icon")) {
                    ImageIcon imageIcon = (ImageIcon) StyleConstants.getIcon(fileBean.getStyledDocument().getCharacterElement(i).getAttributes());
                    DocumentDto documentDto = new DocumentDto(imageIcon);
                    DaoReadWriteFile.saveImage(imageIcon, documentDto.getIconId());        // 保存图片
                    i++;
                    documentDtoList.add(documentDto);
                } else {
                    Element element = fileBean.getStyledDocument().getCharacterElement(i);
                    int length = element.getEndOffset() - element.getStartOffset();
                    AttributeSet attributeSet = element.getAttributes();
                    String text = null;
                    try {
                        text = fileBean.getStyledDocument().getText(i, length);
                    } catch (BadLocationException e1) {
                        e1.printStackTrace();
                    }
                    DocumentDto documentDto = new DocumentDto(text, length);
                    documentDto.setBold(StyleConstants.isBold(attributeSet));
                    documentDto.setFontSize(StyleConstants.getFontSize(attributeSet));
                    documentDto.setForeGround(StyleConstants.getForeground(attributeSet));
                    documentDto.setUnderLine(StyleConstants.isUnderline(attributeSet));
                    documentDto.setItalic(StyleConstants.isItalic(attributeSet));
                    i += length;
                    documentDtoList.add(documentDto);
                }
            }

            StringBuffer documentSB = new StringBuffer();
            for (DocumentDto documentDto : documentDtoList) {
                documentSB.append(documentDto.toString()).append("\n");
            }
            DaoReadWriteFile.reWriteFile(IConstant.PATH
                            + fileBean.getId() + ".document",
                    documentSB.toString(), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除多余照片
     *
     * @param id
     * @return
     */
    private void deleteImageName(String id) {
        List<String> list = new ArrayList<>();
        String documentContent = DaoReadWriteFile.readFile(IConstant.PATH + id + ".document");
        if (documentContent != null) {
            String[] documentArray = documentContent.split("\n");
            for (String documentStr : documentArray) {
                if (documentStr == null || documentStr.length() == 0 || documentStr.equals("\r")) {
                    continue;
                }
                String[] array = documentStr.split(";");
                String type = array[0].split("=")[1];
                if ("icon".equals(type)) {
                    list.add(IConstant.IMAGE_PATH + array[1].split("=")[1] + ".png");
                }
            }
            if (!list.isEmpty()) {
                DaoReadWriteFile.deleteFileByList(list);
            }

        }

    }


    @Override
    public void update(FileBean fileBean) {

    }

    @Override
    public List<FileBean> getDirectory() {
        System.out.println("查询目录结构：getDirectory============");
        List<FileBean> fileBeanList = new ArrayList<>();
        String content = null;
        try {
            content = DaoReadWriteFile.readTreeFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(content);
        String[] arrStrNote = content.split("\r\n");
        for (String string : arrStrNote) {
            String[] strNote = string.split(",");
            FileBean fileBean = new FileBean(Long.parseLong(strNote[0]), Long.parseLong(strNote[1]), strNote[2], null);
            if(strNote.length > 3){
                fileBean.setPassword(strNote[3]);
            }
            fileBeanList.add(fileBean);
        }
        return fileBeanList;
    }

    @Override
    public void getJTreeNodeById(String id, JTextPane jTextPane) {
        System.out.println("查根据id查询文本信息：getJTreeNodeById============");
        String textContent = DaoReadWriteFile.readFile(IConstant.PATH + id);
        if (textContent == null) {
            return;
        }
        textContent = textContent.replaceAll("\r", "");
        String documentContent = DaoReadWriteFile.readFile(IConstant.PATH + id + ".document");
        if (documentContent == null) {
            return;
        }
        List<DocumentDto> documentDtoList = new ArrayList<>();
        String[] documentArray = documentContent.split("\n");
        Document document = jTextPane.getStyledDocument();
        SimpleAttributeSet attrSet = null;


        String foreGround = null;
        int red = 0, green = 0, blue = 0;
        DocumentDto documentDto = null;
        int offset = 0;
        for (String documentStr : documentArray) {
            documentDto = new DocumentDto();
            if (documentStr == null || documentStr.length() == 0 || documentStr.equals("\r")) {
                continue;
            }
            String[] array = documentStr.split(";");
            documentDto.setType(array[0].split("=")[1]);
            if (documentDto.isText()) {
                documentDto.setLength(Integer.valueOf(array[1].split("=")[1]));
                documentDto.setBold(Boolean.parseBoolean(array[2].split("=")[1]));
                documentDto.setFontSize(Integer.valueOf(array[3].split("=")[1]));
                foreGround = array[4].split("=")[1];
                red = Integer.valueOf(foreGround.split(",")[0]);
                green = Integer.valueOf(foreGround.split(",")[1]);
                blue = Integer.valueOf(foreGround.split(",")[2]);
                documentDto.setForeGround(new Color(red, green, blue));
                documentDto.setUnderLine(Boolean.parseBoolean(array[5].split("=")[1]));
                documentDto.setItalic(Boolean.parseBoolean(array[6].split("=")[1]));
                int endIndex = offset + documentDto.getLength();
                if (endIndex > textContent.length()) {
                    endIndex = textContent.length();
                }
                documentDto.setText(textContent.substring(offset, endIndex));
                offset += documentDto.getLength();
            } else {
                documentDto.setIconId(array[1].split("=")[1]);
                ImageIcon imageicon = DaoReadWriteFile.readImage(documentDto.getIconId());
                documentDto.setIcon(imageicon);
            }

            documentDtoList.add(documentDto);
        }


        for (DocumentDto bean : documentDtoList) {
            if (bean.isText()) {
                attrSet = new SimpleAttributeSet();
                StyleConstants.setForeground(attrSet, bean.getForeGround());
                StyleConstants.setBold(attrSet, bean.isBold());
                StyleConstants.setFontSize(attrSet, bean.getFontSize());
                StyleConstants.setUnderline(attrSet, bean.underLine);
                StyleConstants.setItalic(attrSet, bean.isItalic());

                try {
                    document.insertString(document.getLength(), bean.getText(), attrSet);
                } catch (BadLocationException e1) {
                    e1.printStackTrace();
                }
            } else {
                Icon icon = bean.getIcon();
                jTextPane.insertIcon(icon);
            }
        }
    }

    @Override
    public void updateTree() {
        DaoReadWriteFile.createTreeFile(ObjectConstant.treeBiz
                .noteToList(JTreeBiz.rootNote));
    }

    @Override
    public void updateTreeNode(JTreeNode jTreeNode) {

    }

    class DocumentDto {
        private String type = "content";        //content文字,icon图片
        private Icon icon = null; //图片
        private String text = null; // 文本内容
        private int length = 1; // 长度
        private boolean bold = false;
        private int fontSize;
        private Color foreGround;
        private String iconId = null;
        private boolean underLine = false;
        private boolean italic = false;

        public String getIconId() {
            return iconId;
        }

        public void setIconId(String iconId) {
            this.iconId = iconId;
        }

        public DocumentDto(Icon icon) {
            this.type = "icon";
            this.icon = icon;
            this.iconId = UUID.randomUUID().toString();
        }

        public DocumentDto(String text, int length) {
            this.text = text;
            this.length = length;
        }

        public DocumentDto() {
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        public int getLength() {
            return length;
        }

        public void setLength(int length) {
            this.length = length;
        }

        public Icon getIcon() {
            return icon;
        }

        public void setIcon(Icon icon) {
            this.icon = icon;
        }

        public boolean isBold() {
            return bold;
        }

        public void setBold(boolean bold) {
            this.bold = bold;
        }

        public int getFontSize() {
            return fontSize;
        }

        public void setFontSize(int fontSize) {
            this.fontSize = fontSize;
        }

        public Color getForeGround() {
            return foreGround;
        }

        public void setForeGround(Color foreGround) {
            this.foreGround = foreGround;
        }

        public boolean isText() {
            return "content".equals(this.getType());
        }

        public boolean isUnderLine() {
            return underLine;
        }

        public void setUnderLine(boolean underLine) {
            this.underLine = underLine;
        }

        public boolean isItalic() {
            return italic;
        }

        public void setItalic(boolean italic) {
            this.italic = italic;
        }

        @Override
        public String toString() {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("type=").append(this.getType()).append(";");
            if (this.isText()) {  //如果是文本类型
                stringBuffer.append("length=").append(this.getLength()).append(";");
                stringBuffer.append("bold=").append(this.isBold()).append(";");
                stringBuffer.append("fontSize=").append(this.getFontSize()).append(";");
                stringBuffer.append("foreGround=").append(this.getForeGround().getRed())
                        .append(",").append(this.getForeGround().getGreen())
                        .append(",").append(this.getForeGround().getBlue()).append(";");
                stringBuffer.append("underLine=").append(this.isUnderLine()).append(";");
                stringBuffer.append("italic=").append(this.isItalic()).append(";");
            } else {
                stringBuffer.append("iconId=").append(this.getIconId()).append(";");
            }
            return stringBuffer.toString();
        }
    }

    private static class DaoReadWriteFile {

        /**
         * true表示加密，false表示不加密
         */
        public static boolean isEncode = true;

        public static String ENCODING = "GBK";

        /**
         * 给文件写入内容
         *
         * @param path
         * @param content
         * @throws FileNotFoundException
         */
        public static void writeFile(String path, String content, boolean isEncode) throws FileNotFoundException, UnsupportedEncodingException {
            if (isEncode) {
                content = Base64.encode(content);       // 加密
            }
            FileOutputStream fos;
            PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(path), ENCODING));
            pw.write(content);
            pw.flush();
            pw.close();
        }



        /**
         * 清空一个文件
         *
         * @param path
         * @throws IOException
         */
        public static void clearFile(String path) throws IOException {
            File file = new File(path);
            RandomAccessFile rf = null;
            FileChannel fc = null;
            rf = new RandomAccessFile(file, "rw");
            fc = rf.getChannel();
            fc.truncate(0);
            fc.close();
            rf.close();
        }

        /**
         * 重新给文件写入内容
         *
         * @param path
         * @param content
         * @throws IOException
         */
        public static void reWriteFile(String path, String content, boolean isEncode)
                throws IOException {
            clearFile(path);
            writeFile(path, content, isEncode);
        }

        /**
         * 读取树文件
         *
         * @return
         * @throws IOException
         */
        public static String readTreeFile() throws IOException {
            return readFile(IConstant.PATH_TREE_FILE, false);
        }

        /**
         * 根据路劲读取文件
         *
         * @param path
         * @return
         */
        public static String readFile(String path) {
            return readFile(path, true);
        }

        /**
         * 根据路劲读取文件
         *
         * @param path
         * @return
         */
        public static String readFile(String path, boolean isEncode) {
            BufferedReader bufread = null;
            String read = null;
            File file = new File(path);
            if (!file.exists()) {
                return null;
            }
            StringBuilder sb = new StringBuilder();
            try {
                bufread = new BufferedReader(new InputStreamReader(new FileInputStream(file), ENCODING));
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                while ((read = bufread.readLine()) != null) {
                    sb.append(read + "\r\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (isEncode) {
                return Base64.decode(sb.toString());        //解码
            } else {
                return sb.toString();

            }
        }

        /**
         * 根据list集合创建文件
         *
         * @param listNote
         */
        public static void createTreeFile(List<JTreeNode> listNote) {
            StringBuilder sb = new StringBuilder();
            for (JTreeNode treeNote : listNote) {
                sb.append(treeNote.treeNodeId + "," + treeNote.parentId + ","
                        + treeNote.getUserObject() + "," + treeNote.getPassword() + "\r\n");
            }
            try {
                reWriteFile(IConstant.PATH_TREE_FILE, sb.toString(), false);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        public static void saveImage(ImageIcon imageIcon, String imageName) {
            Image image = imageIcon.getImage();
            BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = bi.createGraphics();
            g2d.drawImage(image, 0, 0, null);
            g2d.dispose();
            try {
                ImageIO.write(bi, "png", new File(IConstant.IMAGE_PATH + imageName + ".png"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public static ImageIcon readImage(String imageName) {
            ImageIcon image = new ImageIcon(new File(IConstant.IMAGE_PATH + imageName + ".png").getAbsoluteFile().toString());
            return image;
        }

        /**
         * 根据名称删除文件
         *
         * @param fileNames
         */
        public static void deleteFileByList(List<String> fileNames) {
            for (String fileName : fileNames) {
                File file = new File(fileName);
                if (file.exists() && file.isFile()) {
                    file.delete();
                }
            }
        }

    }
}




